perm filename SAIL.PUB[DOC,AIL]28 blob
sn#259045 filedate 1977-01-21 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00003 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 This addendum describes changes and additions to Sail since the August 1976
C00008 00003
C00012 ENDMK
C⊗;
This addendum describes changes and additions to Sail since the August 1976
manual, AIM-289.
.sec(double precision)
Double precision floating-point arithmetic is available.
Use the <type_qualifier> LONG in declarations. For example,
.exa
LONG REAL X,Y,Z;
LONG REAL ARRAY XA[0:N];
.endexa
Currently LONG has meaning only when it appears as part of LONG REAL.
(At some future time LONG INTEGERs may also exist.)
The runtime routines LREALIN and LREALSCAN operate the same as REALIN and
REALSCAN, except for returning LONG REAL values. The routine CVEL takes a
LONG REAL value and returns a string representation like that of CVE,
except that "@@" is used to signify LONG when delimiting the exponent.
Any of "@", "@@", "E", or "D" are acceptable exponent delimiters to
LREALIN and LREALSCAN.
Variables which are declared LONG REAL are represented in KI10 hardware
format double precision, take two consecutive words of storage, and
provide 62 bits of precision (approximately 18 decimal digits) to
represent the fraction part of a floating-point number. Regular REAL
variables occupy a single word and have 27 bits (8 decimal digits) of
precision. The exponent range of both REAL and LONG REAL variables
is from -128 to 127, where 2↑127 is approximately 10↑38.
LONG REAL is a dominant type in arithmetic operations +-*/%↑ MAX MIN and
arithmetic relationals <>=≠≤≥. If one operand is LONG REAL then both
operands will be converted to LONG REAL (if necessary) before performing
the operation. An exponentiation involving a LONG REAL to a positive
integer constant is an exception to this rule. The type coercion path is
linear: STRING ↔ INTEGER ↔ REAL ↔ LONG REAL. Conversion from REAL to
LONG REAL is performed by assigning the (only) word of the REAL to the
most significant word of the LONG REAL and setting the second (least
significant) word of the LONG REAL to zero. Conversion from LONG REAL to
REAL is by UUO which rounds.
Arithmetic and assignment operations are compiled into DFAD, DFSB, DFMP,
DFDV, DMOVE, DMOVEM instructions. The Sail operations ASH, LSH, ROT,
LAND, LOR, EQV, XOR are performed on both words (ASHC, LSHC, ROTC, 2 ANDs,
2 IORs, etc.). LOCATION of a LONG REAL variable gives an address E such
that DMOVE AC,E fetches the appropriate words of memory. When passed by
value as an actual parameter to a procedure, both words are placed on the
P stack: PUSH P,X ↔ PUSH P,X+1. LONG REAL fields in record classes are
handled much like STRING fields, except that the address in the record
field points to the first word of a 2-word block (rather than to the
second word as in the case with STRINGs).
LONG REAL ARRAYs are stored as contiguous blocks of 2-word values.
ARRTRAN done on two LONG REAL arrays is a transparent operation, but for
ARRYIN, ARRYOUT, or ARRBLT the actual word count is specified; think about
whether you should multiply by 2! At runtime the array descriptor for a
LONG ARRAY has bit 12 (40,,0 bit) set in MULT(n), the multiplier for the
last dimension (which would otherwise be =1). Similarly, a LONG ARRAY is
allocated by setting bit 12 (40,,0) bit in the parameter which specifies
the number of dimensions to ARMAK.
Runtime support for LEAP items with LONG REAL datums does not yet
exist, although the compiler does generate suitable code.
.sec(Declarations and Scope)
In order for the notion of scope to work properly, declarations must occur
before use. For example, the compiler will think that K is undefined in
.exa
BEGIN "FOO"
PROCEDURE BAR; BEGIN PRINT(K) END;
INTEGER K;
END "FOO"
.endexa
even though the reference to PRINT(K) is legal by the ALGOL60 notion of scope.
.sec(Two-character Operators)
The compiler now recognizes "**" for "↑", ":=" for "←",
"<=" for "≤", and ">=" for "≥".
.sec(Requires)
REQUIRE OVERLAP_OK; will suppress the message which occurs at initialization
when two programs have declared items.
REQUIRE VERIFY_DATUMS; causes the compiler to generate three additional instructions
for each DATUM reference, to make sure (dynamically, at run time) that the type
of the item in the DATUM construct is the same as the compiler expected.
This is similar to (the unimplimented effect of) declaring all itemvars CHECKED.
It is planned that VERIFY_DATUMS will soon be a bit in the /A switch
and that the corresponding REQUIRE will disappear.
REQUIRE PROCESSES; insures that MAINPR, the main process, is initialized.
You need not specify this REQUIRE if you use APPLY or SPROUT, but if the
only use of processes is via INTSET then you must REQUIRE PROCESSES;.
.sec(CASE statement)
In an explicitly numbered CASE statement the word ELSE can appear where
a bracketed case number is normally used. The statement following the ELSE is a
catch-all for any case number not mentioned, including anything which
would otherwise generate a CASE index error. For example,
CASE K OF BEGIN [3] J←3; ELSE J←4; [5] J←5 END
is another way of accomplishing
IF K=3 THEN J←3
ELSE IF K=5 THEN J←5
ELSE J←4
A CASE statement containing an ELSE case does not generate a call to the CSERR
runtime routine, and in addition the jump table usually contains only
max_case - min_case +1 words (rather than max_case +1).